/*
 * This file is a part of the SWFer project.
 *
 * Copyright (C) 2012 Michael Bradshaw <mjbshaw@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

#include "SimpleSwf.hpp"

#include "ByteReader.hpp"
#include "ByteWriter.hpp"

#include "Decode.hpp"
#include "Encode.hpp"

#include <fstream>
#include <iostream>

namespace swfer
{

SimpleSwf::SimpleSwf()
{
}

SimpleSwf::SimpleSwf(const std::string& path)
{
	open(path);
}

void SimpleSwf::open(const std::string& path)
{
    std::ifstream file(path, std::ios::binary);

    ByteReader reader(file);

    reader.read(header);
    std::cout << "signature: ";
    std::cout.write((const char*)header.signature, 3);
    std::cout << std::endl;
    std::cout << "version: " << (int)header.version << std::endl;
    std::cout << "file length: " <<  header.fileLength << std::endl;
    std::cout << "frame bits: " << header.frameSize.bits << std::endl;
    std::cout << "frame xmin: " << header.frameSize.xMin << std::endl;
    std::cout << "frame xmax: " << header.frameSize.xMax << std::endl;
    std::cout << "frame ymin: " << header.frameSize.yMin << std::endl;
    std::cout << "frame ymax: " << header.frameSize.yMax << std::endl;
    std::cout << "fps: " << (int)header.frameRate.integer << '.' << (int)header.frameRate.fraction << std::endl;
    std::cout << "frame count: " << header.frameCount << std::endl;

    Packet packet;
	do
	{
		std::size_t pos = file.tellg();
		packet.data.clear();
		reader.read(packet);
		if (packet.header.code == DEFINE_SOUND)
		{
			Tag<DEFINE_SOUND> tag;
			decode(packet, tag);
			std::cout << "Tag id: " << tag.id << std::endl
				<< "Format: " << tag.format << std::endl
				<< "Rate: " << tag.rate << std::endl
				<< "MP3 Seek Samples: " << tag.record.mp3.seekSamples << std::endl
				<< "Sample count: " << tag.sampleCount << std::endl
				<< "Type: " << tag.type << std::endl
				<< "Size: " << tag.size << std::endl;
		}
		if (packet.header.code == SYMBOL_CLASS)
		{
			Tag<SYMBOL_CLASS> tag;
			decode(packet, tag);
			std::cout << "Number of symbols: " << tag.symbols.size() << std::endl;
			for (std::size_t i = 0; i < tag.symbols.size(); ++i)
			{
				std::cout << i << ": name: " << tag.symbols[i].name << " tag: " << tag.symbols[i].tag << std::endl;
			}
		}
		if (packet.header.code == DO_ABC)
		{
			std::ofstream abc("abc", std::ios::binary);
			abc.write(&packet.data[0], packet.data.size());
		}
		std::cout << pos << '\t' << tagCodeToString(packet.header.code) << "\t" << (int)packet.header.code <<
			"\t" << packet.header.length << std::endl;
	} while (packet.header.code != END);
}

void SimpleSwf::save(const std::string& path) const
{
	std::ofstream file(path, std::ios::binary);
	ByteWriter writer(file);

	writer.write(header);

	for (auto s = sounds.cbegin(); s != sounds.cend(); ++s)
	{
		std::vector<Packet> v = encode(*s);

		for (auto p = v.cbegin(); p != v.cend(); ++p)
		{
			writer.write(*p);
		}
	}
	
	writer.write(encode(Tag<END>()));

	header.fileLength = static_cast<uint32_t>(file.tellp());
	file.seekp(4, std::ios::beg);
	writer.write(header.fileLength);
}

const std::list<SimpleSound>& SimpleSwf::getSounds() const
{
	return sounds;
}

void SimpleSwf::addSound(const SimpleSound& simpleSound)
{
	sounds.push_back(simpleSound);
}

}